package com.gos.gaoyg.demo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {
    int positionX;
    int positionY;

    int offsetX;
    int offsetY;

    Bitmap allChessman;
    int chessmanX;
    int chessmanY;

    char turn = 'R';
    Chessman CurrentSelect = new Chessman();
    Chessman unused = new Chessman();
    Chessman SelChessman = unused;

    ImageView ivRResult;
    ImageView ivBResult;
    ImageView Back;

    final int backnum = 100;

    int[][] backs=new int[backnum][5];
    int backpos=0;

    int[][] chessmanInfo ={
            {R.id.Bju1,     0,0,4,0},
            {R.id.Bma1,     1,0,3,0},
            {R.id.Bxiang1,  2,0,2,0},
            {R.id.Bshi1,    3,0,1,0},
            {R.id.Bjiang,   4,0,0,0},
            {R.id.Bshi2,    5,0,1,0},
            {R.id.Bxiang2,  6,0,2,0},
            {R.id.Bma2,     7,0,3,0},
            {R.id.Bju2,     8,0,4,0},
            {R.id.Bpao1,    1,2,5,0},
            {R.id.Bpao2,    7,2,5,0},
            {R.id.Bbing1,   0,3,6,0},
            {R.id.Bbing2,   2,3,6,0},
            {R.id.Bbing3,   4,3,6,0},
            {R.id.Bbing4,   6,3,6,0},
            {R.id.Bbing5,   8,3,6,0},
            {R.id.Rju1,     0,9,4,1},
            {R.id.Rma1,     1,9,3,1},
            {R.id.Rxiang1,  2,9,2,1},
            {R.id.Rshi1,    3,9,1,1},
            {R.id.Rjiang,   4,9,0,1},
            {R.id.Rshi2,    5,9,1,1},
            {R.id.Rxiang2,  6,9,2,1},
            {R.id.Rma2,     7,9,3,1},
            {R.id.Rju2,     8,9,4,1},
            {R.id.Rpao1,    1,7,5,1},
            {R.id.Rpao2,    7,7,5,1},
            {R.id.Rbing1,   0,6,6,1},
            {R.id.Rbing2,   2,6,6,1},
            {R.id.Rbing3,   4,6,6,1},
            {R.id.Rbing4,   6,6,6,1},
            {R.id.Rbing5,   8,6,6,1},
    };

    Chessman[] chessman;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chess);

        //set fullscreen
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        //get screen's height and width
        DisplayMetrics dm = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(dm);

        int screenWidth = dm.widthPixels;
        int screenHeight = dm.heightPixels;

        //calculate position and offset
        positionX = (int)(screenWidth*0.018+0.5);
        positionY = (int)(screenHeight*0.186+0.5);

        offsetX = (int)(screenWidth*0.107 + 0.5);
        offsetY = (int)(screenHeight*0.0557+ 0.5);

        //set back view listener
        ImageView ivBeijing = findViewById(R.id.beijing);
        ivBeijing.setOnClickListener(this);
        ivBeijing.setOnTouchListener(this);

        //set view and listener of chessman
        allChessman = BitmapFactory.decodeResource(this.getResources(),R.drawable.chessman2);
        chessmanY = allChessman.getHeight()/2;
        chessmanX = allChessman.getWidth()/7;

        chessman = new Chessman[32];
        for (int i = 0; i < 32; i++) {
            chessman[i] = new Chessman();
            chessman[i].iv = findViewById(chessmanInfo[i][0]);
            chessman[i].loadImageView(chessmanInfo[i][3], chessmanInfo[i][4]);
            chessman[i].setPosition(chessmanInfo[i][1], chessmanInfo[i][2]);
            chessman[i].iv.setOnClickListener(this);
        }

        //set pointer to current select chessman and target position
        Bitmap bmSel = BitmapFactory.decodeResource(this.getResources(),R.drawable.rim);
        Bitmap bmSelSet = Bitmap.createBitmap(bmSel,0,0,bmSel.getWidth()/2,bmSel.getHeight());

        CurrentSelect.iv = findViewById(R.id.Sel);
        CurrentSelect.iv.setImageBitmap(bmSelSet);
        CurrentSelect.setVisibility(false);

        ivBResult = findViewById(R.id.BResult);
        ivRResult = findViewById(R.id.RResult);
        ivBResult.setX(positionX);
        ivBResult.setY(positionY);
        ivRResult.setX(positionX);
        ivRResult.setY(positionY + 5 * offsetY);
        ivBResult.setVisibility(View.INVISIBLE);
        ivRResult.setVisibility(View.INVISIBLE);

        Back = findViewById(R.id.Back);
        Back.setX(positionX+6*offsetX);
        Back.setY(positionY+12*offsetY);
        Back.setOnClickListener(this);
    }

    public Chessman getChessmanById(int id){
        for (int i = 0; i < 32; i++) {
            if(chessmanInfo[i][0] == id)
                return chessman[i];
        }
        return null;
    }

    public Chessman getChessmanByPos(int x,int y){
        for (int i = 0; i < 32; i++) {
            Chessman cm = getChessmanById(chessmanInfo[i][0]);
            if(cm.px == x && cm.py==y && cm.getVisibility())
                return cm;
        }
        return null;
    }
    public void Record(int x,int y,int cmID){
        int pos = backpos%backnum;
        //sure to go
        if(CurrentSelect.getVisibility()){
            backs[pos][0] = SelChessman.px;
            backs[pos][1] = SelChessman.py;
            backs[pos][2] = x;
            backs[pos][3] = y;
            backs[pos][4] = cmID;
            backpos++;
        }
    }
    public void mvCurseltotar(int x,int y){
        CurrentSelect.setVisibility(false);
        Chessman cm = getChessmanByPos(x,y);
        if(cm != null)
            cm.setVisibility(false);
        SelChessman.setPosition(x,y);


        //change turn
        if(turn == 'R')
            turn = 'B';
        else
            turn = 'R';
    }
    @Override
    public void onClick(View view) {
        if(view.getId() == R.id.Back){
            if(backpos>0 && backs[--backpos%backnum][2]!=0) {
                int pos = backpos%backnum;
                Chessman cm = getChessmanByPos(backs[pos][2], backs[pos][3]);
                backs[pos][2]=0;
                if (cm != null) {
                    cm.setPosition(backs[pos][0], backs[pos][1]);
                    if (backs[pos][4] != 0) {
                        getChessmanById(backs[pos][4]).setVisibility(true);
                    }
                }

                CurrentSelect.setVisibility(false);

                //change turn
                if (turn == 'R')
                    turn = 'B';
                else
                    turn = 'R';
                checkResult();
            }
        }else {
            Chessman chessman = getChessmanById(view.getId());
            if (chessman != null) {//click on chessman
                //check resume the game or not
                if(ivBResult.getVisibility() == View.VISIBLE) {
                    resumeChess();
                } else if(turn != getOwner(view.getId())){
                    //click on the opponent's chessman
                    if(CurrentSelect.getVisibility()) {
                        if(baseRuleCheck(chessman.px, chessman.py,'c')){
                            Record(chessman.px, chessman.py,view.getId());
                            mvCurseltotar(chessman.px, chessman.py);
                            checkResult();
                        }

                    }
                } else {
                    //change select chessman
                    CurrentSelect.setPosition(chessman.px, chessman.py);
                    CurrentSelect.setVisibility(true);
                    SelChessman = chessman;
                }
            }
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if(ivBResult.getVisibility() == View.VISIBLE) {
            resumeChess();
        }else if(CurrentSelect.getVisibility()) {
            int x = (int) (motionEvent.getX() - positionX) / offsetX;
            int y = (int) (motionEvent.getY() - positionY) / offsetY;
            if(baseRuleCheck(x,y ,'b')) {
                Record(x, y, 0);
                mvCurseltotar(x, y);
            }
        }
        return false;
    }

    public void checkResult(){
        if(!getChessmanById(R.id.Rjiang).getVisibility()) {
            ivBResult.setImageResource(R.drawable.win);
            ivRResult.setImageResource(R.drawable.lost);

            ivBResult.setVisibility(View.VISIBLE);
            ivRResult.setVisibility(View.VISIBLE);
        }else if(!getChessmanById(R.id.Bjiang).getVisibility()) {
            ivRResult.setImageResource(R.drawable.win);
            ivBResult.setImageResource(R.drawable.lost);
            ivBResult.setVisibility(View.VISIBLE);
            ivRResult.setVisibility(View.VISIBLE);
        }else{
            ivBResult.setVisibility(View.INVISIBLE);
            ivRResult.setVisibility(View.INVISIBLE);
        }
    }

    public void resumeChess(){
        for (int i = 0; i < 32; i++) {
            chessman[i].setPosition(chessmanInfo[i][1], chessmanInfo[i][2]);
            chessman[i].setVisibility(true);
        }
        ivBResult.setVisibility(View.INVISIBLE);
        ivRResult.setVisibility(View.INVISIBLE);
        turn = 'R';
    }

    public char getOwner(int id){
        for (int i = 0; i < 32; i++) {
            if(chessmanInfo[i][0] == id){
                if(i<16)
                    return 'B';
                else
                    return 'R';
            }
        }

        return 'N';
    }

    public boolean baseRuleCheck(int x,int y,char type){
        boolean result = false;
        if(x>=0 && x<=8 && y>=0 && y<=9 && SelChessman!=unused){
            int SelID = SelChessman.iv.getId();

            switch (SelID){
                case R.id.Bbing1:
                case R.id.Bbing2:
                case R.id.Bbing3:
                case R.id.Bbing4:
                case R.id.Bbing5:
                case R.id.Rbing1:
                case R.id.Rbing2:
                case R.id.Rbing3:
                case R.id.Rbing4:
                case R.id.Rbing5:
                    result = ruleforbing(getOwner(SelID),SelChessman.px,SelChessman.py,x,y,type);
                    break;
                case R.id.Rpao1:
                case R.id.Rpao2:
                case R.id.Bpao1:
                case R.id.Bpao2:
                    result = ruleforpao(getOwner(SelID),SelChessman.px,SelChessman.py,x,y,type);
                    break;
                case R.id.Rju1:
                case R.id.Rju2:
                case R.id.Bju1:
                case R.id.Bju2:
                    result = ruleforju(getOwner(SelID),SelChessman.px,SelChessman.py,x,y,type);
                    break;
                case R.id.Rma1:
                case R.id.Rma2:
                case R.id.Bma1:
                case R.id.Bma2:
                    result = ruleforma(getOwner(SelID),SelChessman.px,SelChessman.py,x,y,type);
                    break;
                case R.id.Rxiang1:
                case R.id.Rxiang2:
                case R.id.Bxiang1:
                case R.id.Bxiang2:
                    result = ruleforxiang(getOwner(SelID),SelChessman.px,SelChessman.py,x,y,type);
                    break;
                case R.id.Rshi1:
                case R.id.Rshi2:
                case R.id.Bshi1:
                case R.id.Bshi2:
                    result = ruleforshi(getOwner(SelID),SelChessman.px,SelChessman.py,x,y,type);
                    break;
                case R.id.Rjiang:
                case R.id.Bjiang:
                    result = ruleforjiang(getOwner(SelID),SelChessman.px,SelChessman.py,x,y,type);
                    break;
                default:
                    break;
            }
        }
        return result;
    }

    public boolean ruleforbing(char owner,int srcx,int srcy,int dstx,int dsty,char type){
        if(owner == 'R'){
            if((dstx==srcx && dsty==srcy-1) ||
                    (dsty==srcy && srcy<5 && (dstx==srcx+1 || dstx==srcx-1)))
                return true;
        }else if(owner == 'B'){
            if((dstx==srcx  && dsty==srcy+1) ||
                    (dsty==srcy && srcy>4 && (dstx==srcx+1 || dstx==srcx-1)))//移动范围有效
                return true;
        }
        return false;
    }

    public boolean ruleforpao(char owner,int srcx,int srcy,int dstx,int dsty,char type){
        int chessNum;
        if(srcx == dstx){
            chessNum = getChessmanCount('x',srcx,srcy,dsty);
        }else if(srcy == dsty){
            chessNum = getChessmanCount('y',srcy,srcx,dstx);
        }else
            return false;
        if(type == 'b')
            return chessNum==0;
        else
            return chessNum==1;
    }

    public boolean ruleforju(char owner,int srcx,int srcy,int dstx,int dsty,char type){
        int chessNum;
        if(srcx == dstx){
            chessNum = getChessmanCount('x',srcx,srcy,dsty);
        }else if(srcy == dsty){
            chessNum = getChessmanCount('y',srcy,srcx,dstx);
        }else
            return false;

        return chessNum==0;
    }

    public boolean ruleforma(char owner,int srcx,int srcy,int dstx,int dsty,char type){
        if(srcx-dstx == 2 && (srcy-dsty == 1 || srcy - dsty == -1) && !(hasChessman(srcx-1,srcy))) //left
            return true;
        else if(srcx-dstx == -2 && (srcy-dsty == 1 || srcy - dsty == -1) && !(hasChessman(srcx+1,srcy))) //right
            return true;
        else if(srcy-dsty == 2 && (srcx-dstx == 1 || srcx - dstx == -1) && !(hasChessman(srcx,srcy-1))) //up
            return true;
        else if(srcy-dsty == -2 && (srcx-dstx == 1 || srcx - dstx == -1) && !(hasChessman(srcx,srcy+1))) //up
            return true;
        else
            return false;
    }

    public boolean ruleforxiang(char owner,int srcx,int srcy,int dstx,int dsty,char type){
        if((owner == 'B' && dsty >4) || (owner == 'R' && dsty <5))
            return false;

        if(srcx-dstx == 2 && srcy-dsty == 2  && !(hasChessman(srcx-1,srcy-1))) //left up
            return true;
        else if(srcx-dstx == -2 && srcy-dsty == 2 && !(hasChessman(srcx+1,srcy-1))) //right up
            return true;
        else if(srcx-dstx == 2 && srcy - dsty == -2 && !(hasChessman(srcx-1,srcy+1))) //left down
            return true;
        else if(srcx-dstx == -2 && srcy - dsty == -2 && !(hasChessman(srcx+1,srcy+1))) //right down
            return true;
        else
            return false;
    }

    public boolean ruleforshi(char owner,int srcx,int srcy,int dstx,int dsty,char type){
        if((owner == 'B' && (dsty>2 || dstx >5 || dstx <3)) ||
                (owner == 'R' && (dsty <7 || dstx>5 || dstx<3)))
            return false;

        if(srcx-dstx == 1 && srcy-dsty == 1) //left up
            return true;
        else if(srcx-dstx == -1 && srcy-dsty == 1) //right up
            return true;
        else if(srcx-dstx == 1 && srcy - dsty == -1) //left down
            return true;
        else if(srcx-dstx == -1 && srcy - dsty == -1) //right down
            return true;
        else
            return false;
    }

    public boolean ruleforjiang(char owner,int srcx,int srcy,int dstx,int dsty,char type){
        if((dsty>2 && dsty <7) || dstx >5 || dstx <3)
            return false;

        if(type == 'c' && srcx == dstx && getChessmanCount('x',srcx,srcy,dsty)==0)
            return true;
        if(srcx-dstx == 0 && (srcy-dsty == 1 || srcy-dsty == -1)) //up down
            return true;
        if((srcx-dstx == 1||srcx-dstx == -1) && srcy-dsty == 0) //right left
            return true;
        else
            return false;
    }

    public boolean hasChessman(int x,int y){
        for (int i = 0; i < 32; i++) {
            Chessman cm = getChessmanById(chessmanInfo[i][0]);
            if(cm.px == x && cm.py==y && cm.getVisibility())
                return true;
        }
        return false;
    }

    public int getChessmanCount(char dir ,int line,int start,int end){
        int added;
        int x;
        int y;
        int count;
        int num=0;

        if(dir == 'x') {
            x = line;
            y = start;
        }else {
            x=start;
            y = line;
        }
        if(start > end) {
            added = -1;
            count = start - end;
        } else {
            added = 1;
            count = end - start;
        }

        for (int i = 0; i < count - 1; i++) {
            if(dir == 'x')
                y+=added;
            else
                x+=added;
            if(hasChessman(x,y))
                num++;
        }

        return num;
    }

    private class Chessman {
        ImageView iv;
        int px;
        int py;

        private void loadImageView(int x,int y){
            Bitmap bmtemp = Bitmap.createBitmap(allChessman,x* chessmanX +3,y* chessmanY, chessmanX -3, chessmanY);
            iv.setImageBitmap(bmtemp);
        }

        private void setPosition(int x,int y){
            if(x>=0 && x<=8 && y>=0 && y<=9) {
                iv.setX(positionX + x * offsetX);
                iv.setY(positionY + y * offsetY);
                px = x;
                py = y;
            }
        }

        private void setVisibility(boolean Visibility){
            if(Visibility){
                iv.setVisibility(View.VISIBLE);
            }else{
                iv.setVisibility(View.INVISIBLE);
            }
        }

        private boolean getVisibility(){
            return iv.getVisibility() == View.VISIBLE;
        }

    }

}
